<template>
  <div class="home-route-container">
    <!-- 页面标题 -->
    <el-page-header @back="handleBack" content="回家路径规划"></el-page-header>

    <el-row :gutter="20" class="page-content">
      <!-- 左侧地图区域 -->
      <el-col :span="16">
        <el-card shadow="hover">
          <div slot="header" class="card-header">
            <span>地图展示</span>
            <el-tooltip content="点击地图可重新选择家的位置">
              <i class="el-icon-question tips-icon"></i>
            </el-tooltip>
          </div>
          <!-- 地图容器 -->
          <div id="amap-container" class="amap-container"></div>
          <!-- 路径规划结果提示（包含出行方式显示） -->
          <div v-if="routeInfo" class="route-tips">
            <el-tag type="success">路径规划成功</el-tag>
            <el-tag type="info" size="small" class="travel-type-tag">
              {{ travelTypeMap[selectedTravelType] }}
            </el-tag>
            <span class="tips-text">
              总距离：{{ routeInfo.distance }} 米 | 预计耗时：{{ routeInfo.duration }} 分钟
            </span>
            <!-- 语音播报控制按钮 -->
            <div class="voice-controls">
              <el-button 
                icon="el-icon-microphone" 
                size="mini" 
                @click="speakTotalRouteInfo"
                :disabled="!speechSupported"
                :title="speechSupported ? '播报路线总信息' : '您的浏览器不支持语音播报'"
              ></el-button>
              <el-button 
                icon="el-icon-headset" 
                size="mini" 
                @click="startVoiceNavigation"
                :disabled="!speechSupported || isNavigating"
                :title="speechSupported ? (isNavigating ? '正在导航中' : '开始语音导航') : '您的浏览器不支持语音播报'"
              ></el-button>
              <el-button 
                icon="el-icon-stop" 
                size="mini" 
                @click="stopVoiceNavigation"
                :disabled="!speechSupported || !isNavigating"
                :title="speechSupported ? '停止语音导航' : '您的浏览器不支持语音播报'"
              ></el-button>
            </div>
          </div>
          <!-- 路径规划错误提示 -->
          <div v-if="routeError" class="route-error">
            <el-tag type="danger">路径规划失败</el-tag>
            <span class="error-text">{{ routeError }}</span>
          </div>
        </el-card>
      </el-col>

      <!-- 右侧功能面板 -->
      <el-col :span="8">
        <el-card shadow="hover">
          <div slot="header">功能操作</div>

          <!-- 家位置设置表单 -->
          <el-form
            ref="homeFormRef"
            :model="homeForm"
            label-width="80px"
            class="home-form"
            :rules="homeFormRules"
          >
            <el-form-item label="家的地址" prop="address">
              <el-input
                v-model="homeForm.address"
                placeholder="请输入详细地址（如：北京市东城区XX路）"
                @change="handleAddressChange"
              ></el-input>
              <!-- 地址建议下拉框 -->
              <el-select
                v-if="addressSuggestions.length > 0"
                v-model="selectedAddress"
                placeholder="选择匹配的地址"
                size="small"
                @change="handleAddressSelect"
                class="address-suggestion"
              >
                <el-option
                  v-for="(item, index) in addressSuggestions"
                  :key="index"
                  :label="item.name"
                  :value="item"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="纬度" prop="latitude">
              <el-input v-model="homeForm.latitude" placeholder="自动生成或手动输入" readonly></el-input>
            </el-form-item>
            <el-form-item label="经度" prop="longitude">
              <el-input v-model="homeForm.longitude" placeholder="自动生成或手动输入" readonly></el-input>
            </el-form-item>
            <el-form-item label="备注" prop="remark">
              <el-input v-model="homeForm.remark" placeholder="如：自己家、父母家"></el-input>
            </el-form-item>

            <!-- 语音设置 -->
            <el-form-item label="语音设置">
              <el-switch 
                v-model="autoSpeakAfterPlan" 
                active-text="规划后自动播报" 
                inactive-text="关闭自动播报"
                :disabled="!speechSupported"
              ></el-switch>
              <el-slider 
                v-model="voiceVolume" 
                :min="0" 
                :max="1" 
                :step="0.1" 
                show-input 
                input-size="mini"
                style="margin-top: 10px;"
                :disabled="!speechSupported"
                tooltip="none"
              ></el-slider>
              <div class="voice-hint" v-if="!speechSupported">
                <el-tag type="warning" size="mini">您的浏览器不支持语音播报功能</el-tag>
              </div>
            </el-form-item>

            <!-- 出行方式选择 -->
            <el-form-item label="出行方式" v-if="isValidLocation(homeForm) && isValidLocation(currentLocation)">
              <el-select
                v-model="selectedTravelType"
                placeholder="选择出行方式"
                size="medium"
                class="travel-type-select"
                @change="clearRouteInfo"
              >
                <el-option
                  v-for="(type, key) in travelTypeMap"
                  :key="key"
                  :label="type"
                  :value="key"
                  :disabled="!isTravelTypeSupported(key)"
                >
                  <i :class="getTravelTypeIcon(key)" class="travel-type-icon"></i>
                  <span class="travel-type-label">{{ type }}</span>
                </el-option>
              </el-select>
            </el-form-item>

            <!-- 功能按钮组 -->
            <el-form-item class="btn-group">
              <el-button
                type="primary"
                icon="el-icon-save"
                @click="handleSaveHomeLocation"
                :loading="saveLoading"
              >
                保存家位置
              </el-button>
              <el-button
                type="info"
                icon="el-icon-location"
                @click="handleGetCurrentLocation"
                :loading="locationLoading"
              >
                获取当前位置
              </el-button>
            </el-form-item>

            <!-- 路径规划按钮 -->
            <el-form-item v-if="isValidLocation(homeForm) && isValidLocation(currentLocation)">
              <el-button
                type="success"
                :icon="getTravelTypeIcon(selectedTravelType)"
                @click="handlePlanRoute"
                :loading="routeLoading"
                class="route-btn"
              >
                开始规划{{ travelTypeMap[selectedTravelType] }}路线
              </el-button>
            </el-form-item>
            <el-form-item v-else>
              <el-button type="success" icon="el-icon-navigation" disabled class="route-btn">
                请先设置家位置并获取当前位置
              </el-button>
            </el-form-item>
          </el-form>
        </el-card>

        <!-- 路径详情面板 -->
        <el-card shadow="hover" v-if="routeSteps.length > 0" class="route-detail-card">
          <div slot="header" class="detail-header">
            <span>路径详情</span>
            <el-tag size="mini" :class="getTravelTypeTagClass(selectedTravelType)">
              {{ travelTypeMap[selectedTravelType] }}
            </el-tag>
          </div>
          <el-scrollbar style="height: 300px;" class="route-scroll">
            <!-- 修复：将两个:class合并为一个数组形式 -->
            <div 
              class="route-step-item" 
              v-for="(step, index) in routeSteps" 
              :key="index"
              :class="[getStepItemClass(index, step), { 'current-step': currentVoiceStep === index }]"
              @click="speakStep(index)"
            >
              <el-avatar :size="24" :class="getStepAvatarClass(index, selectedTravelType)">
                <i :class="getStepIcon(index, step, selectedTravelType)"></i>
              </el-avatar>
              <div class="step-content">
                <div class="step-desc">{{ step.instruction }}</div>
                <div class="step-info">
                  <span>距离：{{ step.distance }} 米</span>
                  <span>耗时：{{ Math.ceil(step.duration / 60) }} 分钟</span>
                  <!-- 公交/驾车显示额外信息 -->
                  <span v-if="selectedTravelType !== 'walking' && step.road">{{ step.road }}</span>
                </div>
              </div>
            </div>
          </el-scrollbar>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import AMapLoader from '@amap/amap-jsapi-loader'
import { saveOrUpdateHomeLocation, getHomeLocation, planHomeRoute } from '@/api/system/home'

export default {
  name: 'HomeRoute',
  data() {
    // 坐标有效性校验函数
    const checkLatitude = (rule, value, callback) => {
      const lat = parseFloat(value)
      if (!value) {
        callback(new Error('请选择或生成纬度'))
      } else if (isNaN(lat) || lat < -90 || lat > 90) {
        callback(new Error('纬度必须在 -90 到 90 之间'))
      } else {
        callback()
      }
    }
    const checkLongitude = (rule, value, callback) => {
      const lng = parseFloat(value)
      if (!value) {
        callback(new Error('请选择或生成经度'))
      } else if (isNaN(lng) || lng < -180 || lng > 180) {
        callback(new Error('经度必须在 -180 到 180 之间'))
      } else {
        callback()
      }
    }

    return {
      // 地图实例
      map: null,
      // 标记点实例
      homeMarker: null,
      currentMarker: null,
      // 路径实例
      polyline: null,
      // 加载状态
      saveLoading: false,
      locationLoading: false,
      routeLoading: false,
      addressResolving: false, // 地址解析加载状态
      // 家位置表单
      homeForm: {
        address: '',
        latitude: null,
        longitude: null,
        remark: ''
      },
      // 当前位置
      currentLocation: {
        latitude: null,
        longitude: null
      },
      // 地址建议
      addressSuggestions: [],
      selectedAddress: null,
      // 表单校验规则
      homeFormRules: {
        address: [{ required: true, message: '请输入家的地址', trigger: 'blur' }],
        latitude: [{ required: true, validator: checkLatitude, trigger: 'blur' }],
        longitude: [{ required: true, validator: checkLongitude, trigger: 'blur' }]
      },
      // 路径信息
      routeInfo: null,
      // 路径步骤
      routeSteps: [],
      // 路径错误信息
      routeError: '',
      // 出行方式配置
      selectedTravelType: 'driving', // 默认驾车
      travelTypeMap: {
        driving: '驾车',
        transit: '公交',
        walking: '步行'
      },
      // 出行方式支持状态（可根据API能力调整）
      travelTypeSupport: {
        driving: true,
        transit: true,
        walking: true
      },
      // 出行方式样式配置
      travelTypeStyle: {
        driving: {
          color: '#3699FF', // 蓝色
          icon: 'el-icon-car',
          tagClass: 'el-tag--primary'
        },
        transit: {
          color: '#67C23A', // 绿色
          icon: 'el-icon-bus',
          tagClass: 'el-tag--success'
        },
        walking: {
          color: '#E6A23C', // 橙色
          icon: 'el-icon-user',
          tagClass: 'el-tag--warning'
        }
      },
      // 语音播报相关
      speechSupported: 'speechSynthesis' in window, // 检测浏览器是否支持语音合成
      autoSpeakAfterPlan: true, // 规划后是否自动播报
      voiceVolume: 0.7, // 语音音量
      isNavigating: false, // 是否正在进行语音导航
      currentVoiceStep: -1, // 当前语音播报的步骤索引
      speechQueue: [], // 语音播报队列
      speechUtterance: null, // 当前语音实例
      navigationInterval: null // 导航间隔计时器
    }
  },
  mounted() {
    // 确保DOM完全渲染后初始化地图
    this.$nextTick(() => {
      const mapContainer = document.getElementById('amap-container');
      if (!mapContainer) {
        this.$message.error('地图容器不存在，初始化失败');
        console.error('amap-container DOM元素未找到');
        return;
      }
      this.initMap();
      
      // 初始化语音合成设置
      if (this.speechSupported) {
        // 设置默认音量
        window.speechSynthesis.volume = this.voiceVolume;
      }
    });
  },
  watch: {
    // 监听音量变化
    voiceVolume(val) {
      if (this.speechSupported) {
        window.speechSynthesis.volume = val;
      }
    }
  },
  beforeDestroy() {
    // 组件销毁时停止语音导航
    this.stopVoiceNavigation();
  },
  methods: {
    /**
     * 校验位置信息是否有效（经纬度非空且为有效数字）
     */
    isValidLocation(location) {
      if (!location || !location.latitude || !location.longitude) return false
      const lat = parseFloat(location.latitude)
      const lng = parseFloat(location.longitude)
      return !isNaN(lat) && !isNaN(lng) && lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180
    },

    /**
     * 校验单个坐标点是否有效
     */
    isValidPoint(point) {
      if (!Array.isArray(point) || point.length !== 2) return false
      const lng = parseFloat(point[0])
      const lat = parseFloat(point[1])
      return !isNaN(lng) && !isNaN(lat) && 
             lng >= -180 && lng <= 180 && 
             lat >= -90 && lat <= 90
    },

    /**
     * 安全地创建LngLat对象
     */
    safeCreateLngLat(lng, lat) {
      try {
        // 先进行有效性校验
        if (isNaN(lng) || isNaN(lat) || lng < -180 || lng > 180 || lat < -90 || lat > 90) {
          throw new Error(`无效的经纬度值: ${lng}, ${lat}`)
        }
        return new window.AMap.LngLat(lng, lat)
      } catch (error) {
        console.error('创建LngLat失败:', error)
        return null
      }
    },

    /**
     * 初始化地图
     */
    initMap() {
      AMapLoader.load({
        key: "8f4eabe9f6c9d4cf051252e89265a901",  // JS API Key
        secretKey: "4a118d5609515008d24605e5fadd9f08",  // 安全密钥
        version: "2.0",
        // 加载所需插件，包括多种出行方式规划
        plugins: ['AMap.Geolocation', 'AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.Driving', 'AMap.Transit', 'AMap.Walking', 'AMap.Autocomplete']
      }).then(AMap => {
        window.AMap = AMap;
        
        // 安全创建地图实例
        try {
          const mapContainer = document.getElementById('amap-container');
          this.map = new AMap.Map(mapContainer, {
            zoom: 13,
            center: this.safeCreateLngLat(116.397470, 39.908823) || [116.397470, 39.908823],
            resizeEnable: true
          })

          // 地图点击事件：选择家的位置
          this.map.on('click', (e) => {
            const { lng, lat } = e.lnglat;
            
            // 1. 立即更新经纬度
            this.homeForm.longitude = lng.toFixed(6);
            this.homeForm.latitude = lat.toFixed(6);
            
            // 2. 显示加载提示
            this.$message.info('正在获取点击位置的地址信息...');
            
            // 3. 调用地址反查
            this.getAddressByLngLat(lng, lat);
            
            // 4. 立即更新地图标记
            this.addHomeMarker();
          })

          this.loadHomeLocation();
        } catch (error) {
          this.$message.error('地图初始化失败：' + error.message);
          console.error('地图实例创建失败:', error);
        }
      }).catch(error => {
        this.$message.error('地图加载失败：' + error.message);
        console.error('地图API加载错误:', error);
      })
    },

    /**
     * 经纬度反查地址（带重试机制）
     */
    getAddressByLngLat(lng, lat, retryCount = 0) {
      if (!window.AMap || !this.isValidPoint([lng, lat])) {
        console.warn('无效的经纬度，无法反查地址');
        return;
      }
      
      this.addressResolving = true;
      const AMap = window.AMap;
      
      AMap.plugin('AMap.Geocoder', () => {
        const geocoder = new AMap.Geocoder({
          radius: 1000,
          extensions: 'all'
        })
        
        geocoder.getAddress([lng, lat], (status, result) => {
          console.log('地址反查结果:', status, result);
          this.addressResolving = false;
          
          if (status === 'complete' && result.info === 'OK') {
            // 更新地址信息
            this.homeForm.address = result.regeocode.formattedAddress || 
              `${result.regeocode.addressComponent.province || ''}${result.regeocode.addressComponent.city || ''}${result.regeocode.addressComponent.district || ''}${result.regeocode.addressComponent.street || ''}${result.regeocode.addressComponent.streetNumber || ''}`;
            this.$message.success('已获取点击位置的地址信息');
          } else {
            // 重试机制：最多重试2次
            if (retryCount < 2) {
              console.log(`地址反查失败，正在进行第${retryCount + 1}次重试...`);
              setTimeout(() => {
                this.getAddressByLngLat(lng, lat, retryCount + 1);
              }, 1000);
              return;
            }
            
            // 所有重试都失败时
            this.$notify({
              title: '地址反查提示',
              message: '地址反查失败，但已获取经纬度坐标<br>您可以手动填写地址信息',
              dangerouslyUseHTMLString: true,
              duration: 5000,
              type: 'warning'
            });
          }
        })
      })
    },

    /**
     * 加载已保存的家位置
     */
    loadHomeLocation() {
      getHomeLocation().then(response => {
        if (response.data) {
          const { address, latitude, longitude, remark } = response.data
          // 转换为字符串（适配表单显示），同时校验有效性
          const lat = parseFloat(latitude)
          const lng = parseFloat(longitude)
          if (this.isValidLocation({ latitude: lat, longitude: lng })) {
            this.homeForm = {
              address: address || '',
              latitude: lat.toFixed(6),
              longitude: lng.toFixed(6),
              remark: remark || ''
            }
            this.addHomeMarker()
          } else {
            this.$message.warning('已保存的家位置坐标无效，请重新设置')
          }
        }
      }).catch(() => {
        this.$message.warning('未查询到家位置，请先设置')
      })
    },

    /**
     * 添加家位置标记
     */
    addHomeMarker() {
      if (!this.map || !this.isValidLocation(this.homeForm)) {
        console.warn('添加家标记失败：地图未初始化或坐标无效')
        return
      }
      
      const AMap = window.AMap;
      const lng = parseFloat(this.homeForm.longitude)
      const lat = parseFloat(this.homeForm.latitude)
      
      // 安全创建坐标点
      const position = this.safeCreateLngLat(lng, lat)
      if (!position) {
        console.error('无法创建有效的家位置坐标点')
        return
      }
      
      if (this.homeMarker) {
        this.map.remove(this.homeMarker)
      }
      
      this.homeMarker = new AMap.Marker({
        position: position,
        title: '我的家',
        icon: new AMap.Icon({
          size: new AMap.Size(30, 30),
          image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png',
          imageSize: new AMap.Size(30, 30)
        })
      })
      
      this.map.add(this.homeMarker)
      this.map.setCenter(position)
    },

    /**
     * 添加当前位置标记
     */
    addCurrentMarker() {
      if (!this.map || !this.isValidLocation(this.currentLocation)) {
        console.warn('添加当前位置标记失败：地图未初始化或坐标无效')
        return
      }
      
      const AMap = window.AMap;
      const lng = parseFloat(this.currentLocation.longitude)
      const lat = parseFloat(this.currentLocation.latitude)
      
      // 安全创建坐标点
      const position = this.safeCreateLngLat(lng, lat)
      if (!position) {
        console.error('无法创建有效的当前位置坐标点')
        return
      }
      
      if (this.currentMarker) {
        this.map.remove(this.currentMarker)
      }
      
      this.currentMarker = new AMap.Marker({
        position: position,
        title: '当前位置',
        icon: new AMap.Icon({
          size: new AMap.Size(30, 30),
          image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png',
          imageSize: new AMap.Size(30, 30)
        })
      })
      
      this.map.add(this.currentMarker)
      this.map.setCenter(position)
    },

    /**
     * 保存家位置
     */
    handleSaveHomeLocation() {
      this.$refs.homeFormRef.validate((isValid) => {
        if (isValid) {
          // 二次校验坐标有效性
          if (!this.isValidLocation(this.homeForm)) {
            this.$message.warning('坐标无效，请重新选择家的位置')
            return
          }
          
          this.saveLoading = true
          saveOrUpdateHomeLocation(this.homeForm).then(response => {
            this.$message.success(response.msg || '保存成功')
            this.addHomeMarker()
          }).catch(error => {
            this.$message.error(error.msg || '保存失败')
          }).finally(() => {
            this.saveLoading = false
          })
        }
      })
    },

    /**
     * 获取当前位置
     */
    handleGetCurrentLocation() {
      this.locationLoading = true
      if (!navigator.geolocation) {
        this.$message.error('您的浏览器不支持地理定位')
        this.locationLoading = false
        return
      }
      
      navigator.geolocation.getCurrentPosition(
        (position) => {
          const { latitude, longitude } = position.coords
          // 验证获取到的坐标是否有效
          if (this.isValidPoint([longitude, latitude])) {
            this.currentLocation.latitude = latitude.toFixed(6)
            this.currentLocation.longitude = longitude.toFixed(6)
            this.addCurrentMarker()
            this.$message.success('当前位置获取成功')
          } else {
            this.$message.error('获取到无效的位置信息')
            console.error('无效的地理位置坐标:', longitude, latitude)
          }
          this.locationLoading = false
        },
        (error) => {
          let msg = '获取位置失败：'
          switch (error.code) {
            case 1: msg += '请允许定位权限'; break
            case 2: msg += '位置信息不可用'; break
            case 3: msg += '请求超时'; break
            default: msg += '未知错误'
          }
          this.$message.error(msg)
          this.locationLoading = false
          this.currentLocation = { latitude: null, longitude: null }
        }
      )
    },

    /**
     * 规划路径
     */
    handlePlanRoute() {
      // 前置校验
      if (!this.map || !this.isValidLocation(this.homeForm) || !this.isValidLocation(this.currentLocation)) {
        this.$message.warning('位置信息无效，请重新设置')
        return
      }
      
      this.routeLoading = true
      this.routeError = ''
      this.routeSteps = []
      
      if (this.polyline) {
        this.map.remove(this.polyline)
        this.polyline = null
      }
      
      // 传参转成数字类型并验证
      const currentLat = parseFloat(this.currentLocation.latitude)
      const currentLng = parseFloat(this.currentLocation.longitude)
      const homeLat = parseFloat(this.homeForm.latitude)
      const homeLng = parseFloat(this.homeForm.longitude)
      
      if (!this.isValidPoint([currentLng, currentLat]) || !this.isValidPoint([homeLng, homeLat])) {
        this.routeError = '起点或终点坐标无效'
        this.routeLoading = false
        this.$message.error(this.routeError)
        return
      }
      
      // 调用路径规划API，传入出行方式参数
      planHomeRoute(currentLat, currentLng, this.selectedTravelType)
        .then(response => {
          console.log('路径规划原始响应:', response.data)
          
          // 数据解析容错
          let routeData;
          try {
            if (!response.data) throw new Error('路径响应为空');
            routeData = typeof response.data === 'string' 
              ? JSON.parse(response.data) 
              : response.data;
          } catch (e) {
            throw new Error('路径数据解析失败: ' + e.message);
          }
          
          // 校验响应结构
          if (routeData.status !== '1' || !routeData.route || !routeData.route.paths || routeData.route.paths.length === 0) {
            throw new Error(routeData.info || '路径规划失败，无有效路径数据');
          }
          
          const path = routeData.route.paths[0];
          this.routeInfo = {
            distance: path.distance || '0',
            duration: path.duration ? Math.ceil(path.duration / 60) : 0
          };
          
          // 过滤无效步骤（确保有polyline数据）
          this.routeSteps = (path.steps || []).filter(step => 
            step && step.polyline && typeof step.polyline === 'string' && step.polyline.trim() !== ''
          );
          
          this.drawFullRoute(this.routeSteps, [currentLng, currentLat], [homeLng, homeLat]);
          
          // 规划完成后自动播报总信息
          if (this.speechSupported && this.autoSpeakAfterPlan) {
            setTimeout(() => {
              this.speakTotalRouteInfo();
            }, 1000);
          }
        })
        .catch(error => {
          this.routeError = error.message || '路径规划失败';
          this.$message.error(this.routeError);
          console.error('路径规划错误:', error);
        })
        .finally(() => {
          this.routeLoading = false;
        })
    },

    /**
     * 绘制完整路径
     */
    drawFullRoute(steps, startPoint, endPoint) {
      if (!this.map || !steps || steps.length === 0) {
        throw new Error('路径步骤为空，无法绘制');
      }
      
      // 验证起点终点有效性
      if (!this.isValidPoint(startPoint) || !this.isValidPoint(endPoint)) {
        throw new Error('起点或终点坐标无效');
      }
      
      const AMap = window.AMap;
      let fullPath = [];
      let invalidCount = 0;
      
      try {
        // 先添加起点
        fullPath.push(startPoint);
        
        // 处理路径步骤中的坐标
        steps.forEach((step, stepIndex) => {
          if (!step.polyline || typeof step.polyline !== 'string') return;
          
          const coordStrList = step.polyline.split(';').filter(coord => coord.trim() !== '');
          
          coordStrList.forEach((coordStr, coordIndex) => {
            const coordParts = coordStr.split(',');
            if (coordParts.length !== 2) {
              invalidCount++;
              console.warn(`步骤${stepIndex}坐标${coordIndex}格式错误: ${coordStr}（跳过）`);
              return;
            }
            
            const [lngStr, latStr] = coordParts;
            // 严格的格式校验
            if (!/^-?\d+(\.\d+)?$/.test(lngStr) || !/^-?\d+(\.\d+)?$/.test(latStr)) {
              invalidCount++;
              console.warn(`步骤${stepIndex}坐标${coordIndex}格式无效: ${coordStr}（跳过）`);
              return;
            }
            
            const lng = parseFloat(lngStr);
            const lat = parseFloat(latStr);
            
            if (!this.isValidPoint([lng, lat])) {
              invalidCount++;
              console.warn(`步骤${stepIndex}坐标${coordIndex}值无效: ${coordStr}（转换结果: ${lng}, ${lat}，跳过）`);
              return;
            }
            
            fullPath.push([lng, lat]);
          });
        });
        
        // 最后添加终点
        fullPath.push(endPoint);

        // 若末点距家位置过远（>20m），补画直线连接
        try {
          const lastValid = fullPath.length >= 2 ? fullPath[fullPath.length - 2] : null;
          let gap = 0;
          if (lastValid && window.AMap && window.AMap.GeometryUtil) {
            const lastPt = Array.isArray(lastValid) ? lastValid : [lastValid.lng, lastValid.lat];
            const endPt = Array.isArray(endPoint) ? endPoint : [endPoint.lng, endPoint.lat];
            gap = window.AMap.GeometryUtil.distance(
              new window.AMap.LngLat(lastPt[0], lastPt[1]),
              new window.AMap.LngLat(endPt[0], endPt[1])
            );
          }
          if (gap > 20) {
            console.log(`末段距家 ${gap.toFixed(1)}m，自动补线`);
            fullPath.push(endPoint);
          }
        } catch (gapErr) {
          console.warn('计算末段距离失败，已跳过补线逻辑:', gapErr);
        }
        
        // 去重相邻的相同点
        const uniquePath = [];
        fullPath.forEach((point, index) => {
          if (index === 0) {
            uniquePath.push(point);
            return;
          }
          const prevPoint = uniquePath[uniquePath.length - 1];
          if (!(Math.abs(point[0] - prevPoint[0]) < 0.000001 && Math.abs(point[1] - prevPoint[1]) < 0.000001)) {
            uniquePath.push(point);
          }
        });
        fullPath = uniquePath;
        
        // 再次校验路径点数量
        if (fullPath.length < 2) {
          throw new Error(`有效路径点不足（仅${fullPath.length}个，无效点${invalidCount}个），无法绘制路径`);
        }
        
        console.log(`路径坐标处理完成：有效点${fullPath.length}个，过滤无效点${invalidCount}个`);
        
        // 移除已有路径
        if (this.polyline) {
          this.map.remove(this.polyline);
        }
        
        // 安全创建路径点数组
        const safePath = [];
        fullPath.forEach((point, index) => {
          const lngLat = this.safeCreateLngLat(point[0], point[1]);
          if (lngLat) {
            safePath.push(lngLat);
          } else {
            console.error(`路径点${index}无效，已跳过`);
          }
        });
        
        if (safePath.length < 2) {
          throw new Error(`安全路径点不足（仅${safePath.length}个），无法绘制路径`);
        }
        
        // 根据出行方式设置不同的路径颜色
        this.polyline = new AMap.Polyline({
          path: safePath,
          strokeColor: this.travelTypeStyle[this.selectedTravelType].color,
          strokeWeight: 6,
          strokeOpacity: 0.9,
          strokeStyle: 'solid',
          zIndex: 100
        });
        
        this.map.add(this.polyline);
        
        // 调整地图视角
        this.adjustMapView(safePath, startPoint, endPoint);
        
      } catch (error) {
        console.error('绘制路径失败:', error);
        throw new Error('绘制路径失败: ' + error.message);
      }
    },

    /**
     * 调整地图视角
     */
    adjustMapView(pathPoints, startPoint, endPoint) {
      if (!this.map || !pathPoints || pathPoints.length === 0) {
        throw new Error('无效的路径数据，无法调整视角');
      }
      
      const AMap = window.AMap;
      
      try {
        // 创建 bounds 对象
        const bounds = new AMap.Bounds();
        
        // 添加路径点
        pathPoints.forEach(point => {
          bounds.extend(point);
        });
        
        // 确保起点终点被包含
        const safeStart = this.safeCreateLngLat(startPoint[0], startPoint[1]);
        const safeEnd = this.safeCreateLngLat(endPoint[0], endPoint[1]);
        if (safeStart) bounds.extend(safeStart);
        if (safeEnd) bounds.extend(safeEnd);
        
        // 检查bounds是否有效
        const southWest = bounds.getSouthWest();
        const northEast = bounds.getNorthEast();
        if (!southWest || !northEast || 
            isNaN(southWest.lng) || isNaN(southWest.lat) ||
            isNaN(northEast.lng) || isNaN(northEast.lat)) {
          throw new Error('计算的地图范围无效');
        }
        
        // 调整视口
        this.map.setBounds(bounds, false, [50, 50, 50, 50]);
        
        // 规划完成后放大并居中到起点
        const focusPoint = this.safeCreateLngLat(startPoint[0], startPoint[1]);
        if (focusPoint) {
          this.map.setZoomAndCenter(15, focusPoint);
        }
        
      } catch (error) {
        console.warn('使用bounds调整视角失败，尝试备选方案:', error);
        
        try {
          // 备选方案1：使用路径的第一个和最后一个点计算中心
          const firstPoint = pathPoints[0];
          const lastPoint = pathPoints[pathPoints.length - 1];
          
          // 计算中心点
          const centerLng = (firstPoint.lng + lastPoint.lng) / 2;
          const centerLat = (firstPoint.lat + lastPoint.lat) / 2;
          
          const centerPoint = this.safeCreateLngLat(centerLng, centerLat);
          if (centerPoint) {
            // 计算合适的缩放级别
            const distance = AMap.GeometryUtil.distance(firstPoint, lastPoint);
            let zoom = 10;
            if (distance < 1000) zoom = 15;
            else if (distance < 5000) zoom = 13;
            else if (distance < 20000) zoom = 11;
            
            this.map.setZoomAndCenter(zoom, centerPoint);
            return;
          }
        } catch (e) {
          console.warn('备选方案1失败:', e);
        }
        
        try {
          // 备选方案2：使用起点和终点计算中心
          const centerLng = (parseFloat(startPoint[0]) + parseFloat(endPoint[0])) / 2;
          const centerLat = (parseFloat(startPoint[1]) + parseFloat(endPoint[1])) / 2;
          
          const centerPoint = this.safeCreateLngLat(centerLng, centerLat);
          if (centerPoint) {
            this.map.setCenter(centerPoint);
            this.map.setZoom(12);
            return;
          }
        } catch (e) {
          console.warn('备选方案2失败:', e);
        }
        
        // 终极方案：使用默认中心点
        const defaultCenter = this.safeCreateLngLat(116.397470, 39.908823);
        if (defaultCenter) {
          this.map.setCenter(defaultCenter);
          this.map.setZoom(10);
        } else {
          throw new Error('所有视角调整方案均失败');
        }
      }
    },

    /**
     * 地址查询经纬度（带地址建议功能）
     */
    handleAddressChange() {
      if (!this.homeForm.address || !this.map || this.homeForm.address.length < 2) {
        this.addressSuggestions = [];
        return;
      }
      
      this.addressResolving = true;
      const AMap = window.AMap;
      
      // 使用Autocomplete获取地址建议
      AMap.plugin('AMap.Autocomplete', () => {
        const autoOptions = {
          city: '', // 全国范围
          input: this.homeForm.address
        };
        
        const autocomplete = new AMap.Autocomplete(autoOptions);
        
        // 获取地址建议
        autocomplete.search(this.homeForm.address, (status, result) => {
          this.addressResolving = false;
          
          if (status === 'complete' && result.tips && result.tips.length > 0) {
            this.addressSuggestions = result.tips;
          } else {
            this.addressSuggestions = [];
            // 尝试直接搜索地址
            this.searchAddressDirectly();
          }
        });
      });
    },

    /**
     * 直接搜索地址获取坐标
     */
    searchAddressDirectly() {
      if (!this.homeForm.address || !this.map) return;
      
      this.addressResolving = true;
      const AMap = window.AMap;
      
      AMap.plugin('AMap.PlaceSearch', () => {
        const placeSearch = new AMap.PlaceSearch({
          city: '',
          pageSize: 1
        });
        
        placeSearch.search(this.homeForm.address, (status, result) => {
          this.addressResolving = false;
          
          if (status === 'complete' && result.poiList && result.poiList.pois.length > 0) {
            const poi = result.poiList.pois[0];
            if (this.isValidPoint([poi.location.lng, poi.location.lat])) {
              this.homeForm.longitude = poi.location.lng.toFixed(6);
              this.homeForm.latitude = poi.location.lat.toFixed(6);
            } else {
              this.$message.warning('查询到的地址坐标无效');
            }
          } else {
            this.$notify({
              title: '地址解析提示',
              message: '未能解析该地址，建议：<br>1. 检查地址是否正确<br>2. 尝试使用更详细的地址<br>3. 直接在地图上点击选择位置',
              dangerouslyUseHTMLString: true,
              duration: 5000,
              type: 'warning'
            });
          }
        });
      });
    },

    /**
     * 选择地址建议项
     */
    handleAddressSelect(selectedItem) {
      if (!selectedItem || !selectedItem.location) return;
      
      this.homeForm.address = selectedItem.name;
      this.homeForm.longitude = selectedItem.location.lng.toFixed(6);
      this.homeForm.latitude = selectedItem.location.lat.toFixed(6);
      this.addressSuggestions = [];
      
      // 在地图上显示选中的位置
      const position = this.safeCreateLngLat(
        selectedItem.location.lng, 
        selectedItem.location.lat
      );
      if (position) {
        this.map.setCenter(position);
        this.map.setZoom(15);
        this.addHomeMarker();
      }
    },

    /**
     * 返回上一页
     */
    handleBack() {
      this.$router.back()
    },

    /**
     * 出行方式相关方法
     */
    isTravelTypeSupported(type) {
      return this.travelTypeSupport[type] || false;
    },
    
    getTravelTypeIcon(type) {
      return this.travelTypeStyle[type]?.icon || 'el-icon-navigation';
    },
    
    getTravelTypeTagClass(type) {
      return this.travelTypeStyle[type]?.tagClass || 'el-tag--info';
    },
    
    clearRouteInfo() {
      // 切换出行方式时清除现有路径信息
      this.routeInfo = null;
      this.routeSteps = [];
      this.routeError = '';
      this.stopVoiceNavigation(); // 停止语音导航
      if (this.polyline) {
        this.map.remove(this.polyline);
        this.polyline = null;
      }
    },
    
    /**
     * 路径步骤样式相关方法
     */
    getStepAvatarClass(index, type) {
      let baseClass = 'step-avatar';
      if (index === 0) {
        return `${baseClass} start-avatar ${type}-avatar`;
      }
      if (index === this.routeSteps.length - 1) {
        return `${baseClass} end-avatar ${type}-avatar`;
      }
      return `${baseClass} middle-avatar ${type}-avatar`;
    },
    
    getStepIcon(index, step, type) {
      if (index === 0) return 'el-icon-start';
      if (index === this.routeSteps.length - 1) return 'el-icon-end';
      
      // 根据出行方式和步骤信息显示不同图标
      if (type === 'transit' && step.transit) {
        return step.transit.buslines && step.transit.buslines.length > 0 
          ? 'el-icon-bus' 
          : 'el-icon-subway';
      }
      return this.getTravelTypeIcon(type);
    },
    
    getStepItemClass(index, step) {
      return step.transit ? 'transit-step' : '';
    },

    /**
     * 语音播报相关方法
     */
    // 播报路线总信息
    speakTotalRouteInfo() {
      if (!this.speechSupported || !this.routeInfo) return;
      
      // 停止当前任何语音
      this.stopSpeech();
      
      const travelType = this.travelTypeMap[this.selectedTravelType];
      const distance = this.formatDistance(this.routeInfo.distance);
      const text = `从当前位置到${this.homeForm.remark || '家'}的${travelType}路线规划完成，总${distance}，预计耗时${this.routeInfo.duration}分钟。`;
      
      this.speakText(text);
    },
    
    // 播报单个步骤
    speakStep(index) {
      if (!this.speechSupported || !this.routeSteps || index < 0 || index >= this.routeSteps.length) return;
      
      // 停止当前任何语音
      this.stopSpeech();
      
      // 高亮当前步骤
      this.currentVoiceStep = index;
      
      const step = this.routeSteps[index];
      // 格式化步骤文本，去除多余符号
      let instruction = step.instruction.replace(/<[^>]+>/g, '').replace(/【[^】]+】/g, '');
      const distance = this.formatDistance(step.distance);
      
      const text = `步骤${index + 1}：${instruction}，${distance}，预计${Math.ceil(step.duration / 60)}分钟。`;
      
      // 播报完成后取消高亮
      this.speakText(text, () => {
        if (!this.isNavigating) {
          this.currentVoiceStep = -1;
        }
      });
    },
    
    // 开始语音导航（逐步骤播报）
    startVoiceNavigation() {
      if (!this.speechSupported || this.isNavigating || !this.routeSteps || this.routeSteps.length === 0) return;
      
      this.isNavigating = true;
      this.currentVoiceStep = -1;
      
      // 先播报总信息
      this.speakTotalRouteInfo();
      
      // 总信息播报完成后开始步骤导航
      setTimeout(() => {
        this.navigateToStep(0);
      }, 3000);
    },
    
    // 导航到指定步骤
    navigateToStep(index) {
      if (!this.isNavigating || !this.routeSteps || index >= this.routeSteps.length) {
        this.finishNavigation();
        return;
      }
      
      this.currentVoiceStep = index;
      this.speakStep(index);
      
      // 根据步骤距离计算下一步播报延迟时间（每100米约10秒）
      const step = this.routeSteps[index];
      const distance = parseFloat(step.distance) || 100;
      const delay = Math.max(5000, Math.min(30000, distance * 100)); // 5-30秒之间
      
      // 设置下一步计时器
      this.navigationInterval = setTimeout(() => {
        this.navigateToStep(index + 1);
      }, delay);
    },
    
    // 完成导航
    finishNavigation() {
      this.isNavigating = false;
      this.currentVoiceStep = -1;
      clearTimeout(this.navigationInterval);
      
      if (this.speechSupported) {
        this.speakText(`导航结束，您已到达${this.homeForm.remark || '家'}。`);
      }
    },
    
    // 停止语音导航
    stopVoiceNavigation() {
      if (!this.isNavigating) return;
      
      this.stopSpeech();
      this.isNavigating = false;
      this.currentVoiceStep = -1;
      clearTimeout(this.navigationInterval);
    },
    
    // 播放文本
    speakText(text, onEnd = null) {
      if (!this.speechSupported) return;
      
      // 停止任何正在播放的语音
      this.stopSpeech();
      
      // 创建新的语音实例
      this.speechUtterance = new SpeechSynthesisUtterance();
      this.speechUtterance.text = text;
      this.speechUtterance.lang = 'zh-CN';
      this.speechUtterance.volume = this.voiceVolume;
      this.speechUtterance.rate = 1; // 语速
      this.speechUtterance.pitch = 1; // 音调
      
      // 语音结束事件
      if (onEnd && typeof onEnd === 'function') {
        this.speechUtterance.onend = onEnd;
      }
      
      // 播放语音
      window.speechSynthesis.speak(this.speechUtterance);
    },
    
    // 停止当前语音
    stopSpeech() {
      if (!this.speechSupported) return;
      
      window.speechSynthesis.cancel();
      this.speechUtterance = null;
    },
    
    // 格式化距离显示
    formatDistance(distance) {
      const dist = parseFloat(distance);
      if (isNaN(dist)) return '距离未知';
      if (dist >= 1000) {
        return `距离${(dist / 1000).toFixed(1)}公里`;
      } else {
        return `距离${Math.round(dist)}米`;
      }
    }
  }
}
</script>

<style scoped>
.home-route-container {
  padding: 20px;
}

.page-content {
  margin-top: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.tips-icon {
  cursor: pointer;
  color: #666;
  font-size: 16px;
}

.amap-container {
  width: 100%;
  height: 600px;
  border-radius: 4px;
}

.route-tips {
  margin-top: 10px;
  padding: 5px 10px;
  background-color: #f0f9eb;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.route-error {
  margin-top: 10px;
  padding: 5px 10px;
  background-color: #fef0f0;
  border-radius: 4px;
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.tips-text {
  color: #67c23a;
  font-size: 14px;
  flex: 1;
  min-width: 200px;
}

.error-text {
  color: #f56c6c;
  font-size: 14px;
}

.home-form {
  margin-top: 15px;
}

.address-suggestion {
  margin-top: 5px;
  width: 100%;
}

.btn-group {
  display: flex;
  gap: 10px;
  margin-top: 10px;
}

.route-btn {
  width: 100%;
  margin-top: 10px;
}

.route-detail-card {
  margin-top: 20px;
}

.detail-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.route-scroll {
  margin-top: 10px;
}

.route-step-item {
  display: flex;
  gap: 15px;
  padding: 10px 0;
  border-bottom: 1px dashed #eee;
  align-items: flex-start;
  transition: background-color 0.2s;
  cursor: pointer;
}

.route-step-item:hover {
  background-color: #f5f7fa;
}

.route-step-item:last-child {
  border-bottom: none;
}

.current-step {
  background-color: #e6f7ff;
  border-left: 3px solid #1890ff;
  padding-left: 10px;
}

.transit-step {
  border-left: 3px solid #67C23A;
  padding-left: 10px;
}

.step-content {
  flex: 1;
}

.step-desc {
  font-size: 14px;
  margin-bottom: 5px;
  line-height: 1.5;
}

.step-info {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
  font-size: 12px;
  color: #666;
}

.step-avatar {
  margin-top: 3px;
}

.start-avatar {
  background-color: #409eff;
}

.end-avatar {
  background-color: #67c23a;
}

.middle-avatar {
  background-color: #e6a23c;
}

/* 不同出行方式的样式 */
.driving-avatar.middle-avatar {
  background-color: #3699FF;
}

.transit-avatar.middle-avatar {
  background-color: #67C23A;
}

.walking-avatar.middle-avatar {
  background-color: #E6A23C;
}

.travel-type-select {
  width: 100%;
}

.travel-type-icon {
  margin-right: 5px;
}

.travel-type-tag {
  margin-left: 5px;
}

/* 语音控制相关样式 */
.voice-controls {
  display: flex;
  gap: 5px;
  margin-left: auto;
  min-width: 100px;
}

.voice-hint {
  margin-top: 5px;
  font-size: 12px;
}
</style>
